{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Week 1 Exercise Question.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "code",
      "metadata": {
        "id": "y7QztBIVR1tb",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "!pip install tensorflow==2.0.0b1\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "t9HrvPfrSlzS",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import tensorflow as tf\n",
        "print(tf.__version__)\n",
        "\n",
        "# EXPECTED OUTPUT\n",
        "# 2.0.0-beta1 (or later)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "gqWabzlJ63nL",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import tensorflow as tf\n",
        "from tensorflow import keras\n",
        "\n",
        "def plot_series(time, series, format=\"-\", start=0, end=None):\n",
        "    plt.plot(time[start:end], series[start:end], format)\n",
        "    plt.xlabel(\"Time\")\n",
        "    plt.ylabel(\"Value\")\n",
        "    plt.grid(True)\n",
        "\n",
        "def trend(time, slope=0):\n",
        "    return slope * time\n",
        "\n",
        "def seasonal_pattern(season_time):\n",
        "    \"\"\"Just an arbitrary pattern, you can change it if you wish\"\"\"\n",
        "    return np.where(season_time < 0.1,\n",
        "                    np.cos(season_time * 7 * np.pi),\n",
        "                    1 / np.exp(5 * season_time))\n",
        "\n",
        "def seasonality(time, period, amplitude=1, phase=0):\n",
        "    \"\"\"Repeats the same pattern at each period\"\"\"\n",
        "    season_time = ((time + phase) % period) / period\n",
        "    return amplitude * seasonal_pattern(season_time)\n",
        "\n",
        "def noise(time, noise_level=1, seed=None):\n",
        "    rnd = np.random.RandomState(seed)\n",
        "    return rnd.randn(len(time)) * noise_level\n",
        "\n",
        "time = np.arange(4 * 365 + 1, dtype=\"float32\")\n",
        "baseline = 10\n",
        "series = trend(time, 0.1)  \n",
        "baseline = 10\n",
        "amplitude = 40\n",
        "slope = 0.01\n",
        "noise_level = 2\n",
        "\n",
        "# Create the series\n",
        "series = baseline + trend(time, slope) + seasonality(time, period=365, amplitude=amplitude)\n",
        "# Update with noise\n",
        "series += noise(time, noise_level, seed=42)\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time, series)\n",
        "plt.show()\n",
        "\n",
        "# EXPECTED OUTPUT\n",
        "# Chart as in the screencast. First should have 5 distinctive 'peaks'"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UfdyqJJ1VZVu",
        "colab_type": "text"
      },
      "source": [
        "Now that we have the time series, let's split it so we can start forecasting"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "_w0eKap5uFNP",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "split_time = # YOUR CODE HERE\n",
        "time_train = time[:split_time]\n",
        "x_train = series[:split_time]\n",
        "time_valid = time[split_time:]\n",
        "x_valid = series[split_time:]\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_train, x_train)\n",
        "plt.show()\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, x_valid)\n",
        "plt.show()\n",
        "\n",
        "# EXPECTED OUTPUT\n",
        "# Chart WITH 4 PEAKS between 50 and 65 and 3 troughs between -12 and 0\n",
        "# Chart with 2 Peaks, first at slightly above 60, last at a little more than that, should also have a single trough at about 0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bjD8ncEZbjEW",
        "colab_type": "text"
      },
      "source": [
        "# Naive Forecast"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Pj_-uCeYxcAb",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "naive_forecast = series[#YOUR CODE HERE]"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JtxwHj9Ig0jT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, x_valid)\n",
        "plot_series(time_valid, naive_forecast)\n",
        "\n",
        "# Expected output: Chart similar to above, but with forecast overlay"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fw1SP5WeuixH",
        "colab_type": "text"
      },
      "source": [
        "Let's zoom in on the start of the validation period:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "D0MKg7FNug9V",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(# YOUR CODE HERE)\n",
        "plot_series(# YOUR CODE HERE)\n",
        "\n",
        "# EXPECTED - Chart with X-Axis from 1100-1250 and Y Axes with series value and projections. Projections should be time stepped 1 unit 'after' series"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Uh_7244Gsxfx",
        "colab_type": "text"
      },
      "source": [
        "Now let's compute the mean squared error and the mean absolute error between the forecasts and the predictions in the validation period:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "byNnC7IbsnMZ",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(# YOUR CODE HERE)\n",
        "print(# YOUR CODE HERE)\n",
        "# Expected Output\n",
        "# 19.578304\n",
        "# 2.6011968"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WGPBC9QttI1u",
        "colab_type": "text"
      },
      "source": [
        "That's our baseline, now let's try a moving average:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "YGz5UsUdf2tV",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def moving_average_forecast(series, window_size):\n",
        "  \"\"\"Forecasts the mean of the last few values.\n",
        "     If window_size=1, then this is equivalent to naive forecast\"\"\"\n",
        "  # YOUR CODE HERE"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "HHFhGXQji7_r",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "moving_avg = moving_average_forecast(# YOUR CODE HERE)[# YOUR CODE HERE]\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, x_valid)\n",
        "plot_series(time_valid, moving_avg)\n",
        "    \n",
        "# EXPECTED OUTPUT\n",
        "# CHart with time series from 1100->1450+ on X\n",
        "# Time series plotted\n",
        "# Moving average plotted over it"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wG7pTAd7z0e8",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(# YOUR CODE HERE)\n",
        "print(# YOUR CODE HERE)\n",
        "# EXPECTED OUTPUT\n",
        "# 65.786224\n",
        "# 4.3040023"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5pqySF7-rJR4",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "diff_series = (# YOUR CODE HERE)\n",
        "diff_time = # YOUR CODE HERE\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(diff_time, diff_series)\n",
        "plt.show()\n",
        "    \n",
        "# EXPECETED OUTPUT: CHart with diffs"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xPlPlS7DskWg",
        "colab_type": "text"
      },
      "source": [
        "Great, the trend and seasonality seem to be gone, so now we can use the moving average:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QmZpz7arsjbb",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "diff_moving_avg = # YOUR CODE HERE\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plt.show()\n",
        "            \n",
        "# Expected output. Diff chart from 1100->1450 +\n",
        "# Overlaid with moving average"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Gno9S2lyecnc",
        "colab_type": "text"
      },
      "source": [
        "Now let's bring back the trend and seasonality by adding the past values from t – 365:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Dv6RWFq7TFGB",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "diff_moving_avg_plus_past = # YOUR CODE HERE\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plt.show()\n",
        "# Expected output: Chart from 1100->1450+ on X. Same chart as earlier for time series, but projection overlaid looks close in value to it"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "59jmBrwcTFCx",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "\n",
        "print(# YOUR CODE HERE)\n",
        "print(# YOUR CODE HERE)\n",
        "# EXPECTED OUTPUT\n",
        "# 8.498155\n",
        "# 2.327179"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vx9Et1Hkeusl",
        "colab_type": "text"
      },
      "source": [
        "Better than naive forecast, good. However the forecasts look a bit too random, because we're just adding past values, which were noisy. Let's use a moving averaging on past values to remove some of the noise:"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "K81dtROoTE_r",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "diff_moving_avg_plus_smooth_past = # YOUR CODE HERE\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plot_series(time_valid, # YOUR CODE HERE)\n",
        "plt.show()\n",
        "            \n",
        "# EXPECTED OUTPUT:\n",
        "# Similar chart to above, but the overlaid projections are much smoother"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iN2MsBxWTE3m",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "print(# YOUR CODE HERE)\n",
        "print(# YOUR CODE HERE)\n",
        "# EXPECTED OUTPUT\n",
        "# 12.527958\n",
        "# 2.2034433"
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}